package com.ruoyi.business.modbus.service.modbus4j;

import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.ruoyi.business.modbus.domain.ModbusMasterDevice;
import com.ruoyi.business.modbus.domain.ModbusTcpMasterDevice;
import com.ruoyi.business.modbus.service.IModbusCoreService;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.ip.IpParameters;

/**
 * Modbus4J TCP服务实现类
 * 
 * @author ruoyi
 * @date 2024-01-01
 */
@Service("modbus4jTcpService")
public class Modbus4jTcpServiceImpl extends AbstractModbus4jService implements IModbusCoreService
{
    @Override
    protected ModbusMaster createModbusMaster(ModbusMasterDevice modbusMasterEntity) throws Exception
    {
        if (!(modbusMasterEntity instanceof ModbusTcpMasterDevice)) {
            throw new IllegalArgumentException("设备类型必须是ModbusTcpMasterDevice");
        }
        
        ModbusTcpMasterDevice modbusTcpMasterEntity = (ModbusTcpMasterDevice) modbusMasterEntity;
        
        // 创建IP参数
        IpParameters params = new IpParameters();
        params.setHost(modbusTcpMasterEntity.getIpAddress());
        params.setPort(modbusTcpMasterEntity.getPort());
        params.setEncapsulated(modbusTcpMasterEntity.getEncapsulated());
        // 创建Modbus工厂和TCP主站
        ModbusFactory factory = new ModbusFactory();
        ModbusMaster master = factory.createTcpMaster(params, true);//keepAlive=true,表示启用KeepAlive机制
        
        // 初始化主站
        master.init();
        master.setTimeout(modbusTcpMasterEntity.getTimeout());
        master.setRetries(modbusTcpMasterEntity.getRetries());
        
        return master;
    }
    
    @Override
    public Map<String, Object> getImplementationInfo() {
        Map<String, Object> info = new HashMap<>();
        info.put("implementation", "Modbus4jTcpServiceImpl");
        info.put("type", "TCP");
        info.put("description", "Modbus4J TCP服务实现");
        info.put("version", "1.0");
        return info;
    }
}
